package utils

import (
	"fmt"
	"reflect"
)

type TypeFactory struct {
	typeMap map[string]reflect.Type
}

func NewTypeFactory() *TypeFactory {
	rval := &TypeFactory{
		typeMap: make(map[string]reflect.Type),
	}
	return rval
}

var (
	defautlTypeFactory *TypeFactory = NewTypeFactory()
)

func RegisterOfType(name string, c interface{}) {
	defautlTypeFactory.Register(name, c)
}

func NewByRegisterName(name string) (c interface{}, err error) {
	return defautlTypeFactory.New(name)
}

func (this TypeFactory) Register(name string, c interface{}) {
	this.typeMap[name] = reflect.TypeOf(c).Elem()
}

func (this TypeFactory) RegisterType(name string, c reflect.Type) {
	this.typeMap[name] = c.Elem()
}

func (this TypeFactory) New(name string) (c interface{}, err error) {
	if v, ok := this.typeMap[name]; ok {
		c = reflect.New(v).Interface()
	} else {
		err = fmt.Errorf("not found %s struct", name)
	}
	return
}
